/**
 * @file InjectionRes.h
 * @brief The implementation of the injection restriction operator.
 * @author XDDDD
 * @version 
 * @date 2021-06-10
 */

#ifndef __PAISLEYPARK__INJECTIONRES_H__
#define __PAISLEYPARK__INJECTIONRES_H__

#include "RestrictionOperator.h"

template <size_t DIM>
class InjectionRes : public RestrictionOperator<DIM> {
public:
	void operator()(MultigridVector<DIM>& _v, const size_t _M) override;
};

template <size_t DIM>
void InjectionRes<DIM>::operator()(MultigridVector<DIM>& _v, const size_t _M) {
	if(_v.get_N() < _M) {
		std::cout << "The present grids do not lies in the coarest grids" << std::endl;
		std::exit(-1);
	}
	else if(_M <= 1) {
		std::cout << "Can not restrict finer." << std::endl;
		std::exit(-1);
	}
	std::vector<size_t> coord_2h;
	std::vector<size_t> coord_h;
	coord_2h.clear();
	coord_h.clear();
	coord_2h.resize(DIM);
	coord_h.resize(DIM);
	size_t pole = 0;
	size_t num_1d = (1 << _M - 1) + 1;
	double coef = 1.0;
	for(size_t i = 0; i != DIM; i++) {
		coord_2h[i] = 1;
	}
	//Go through all the nodes in the coares grid.
	while(pole != DIM) {
		size_t l = 1;
		for(size_t i = 0; i != DIM; i++) {
			coord_h[i] = 2*coord_2h[i];
		}
		_v(coord_2h, _M - 1) = _v(coord_h, _M);
		//next node on grid 2h.
		pole = 0;
		coord_2h[pole]++;
		while(coord_2h[pole] == num_1d - 1) {
			coord_2h[pole] = 1;
			pole++;
			if(pole == DIM)
				break;
			coord_2h[pole]++;
		}
	}
};
#else
//Do nothing.
#endif
